#ifndef LOGGER_H_
#define LOGGER_H_

#include "netlib/base/log_stream.h"
#include "netlib/base/noncopyable.h"
#include "netlib/base/time_stamp.h"
// #include "netlib/base/log_utils.h"

namespace netlib {

class Logger : NonCopyable {
	using BaseName = LogStream::BaseName;

public:
	enum LogLevel { kTrace, kDebug, kInfo, kWarn, kError, kFatal };

	Logger(int line, BaseName&& file, LogLevel level);
	Logger(int line, BaseName&& file, bool is_abort);
	Logger(int line, const char* file, LogLevel level) : Logger(line, BaseName(file), level) {}
	Logger(int line, const char* file, bool is_abort) : Logger(line, BaseName(file), is_abort) {}
	// Logger(int line, const char* file);
	~Logger();

	LogStream& Stream() { return stream_; }
	static LogLevel Level() { return Logger::min_level; }

private:
	void FormatHeader();
	void UpdateThreadTime();
	void FormatTail();

	int line_;
	BaseName basename_;
	Timestamp time_{Timestamp::Now()};
	LogLevel level_;
	LogStream stream_;

	static LogLevel min_level;
};

const char* StrerrorTl(int save_errno);

#define LOG_TRACE                          \
	if (Logger::Level() <= Logger::kTrace) \
	netlib::Logger(__LINE__, __FILE__, Logger::kTrace).Stream()

#define LOG_DEBUG                          \
	if (Logger::Level() <= Logger::kDebug) \
	netlib::Logger(__LINE__, __FILE__, Logger::kDebug).Stream()

#define LOG_INFO \
	if (Logger::Level() <= Logger::kInfo) netlib::Logger(__LINE__, __FILE__, Logger::kInfo).Stream()

#define LOG_WARN netlib::Logger(__LINE__, __FILE__, Logger::kWarn).Stream()

#define LOG_ERROR netlib::Logger(__LINE__, __FILE__, false).Stream()

#define LOG_FATAL netlib::Logger(__LINE__, __FILE__, true).Stream()

#define LOG_SYSERR netlib::Logger(__LINE__, __FILE__, false).Stream()

#define LOG_SYSFATAL netlib::Logger(__LINE__, __FILE__, true).Stream()
} // namespace netlib
#endif // LOGGER_H_
